/*
 * app_broadcast_retry.c
 *
 *  Created on: 2023年9月4日
 *      Author: HXF
 */
#ifdef HUB_DEVICE
#include "app_hub_api.h"
#else
#include "app_key_value.h"
#include "net_packet.h"
#endif
#include "app_broadcast_retry.h"
#include "app_hub_api_subsidiary.h"
#include "app_filetransport_def.h"
#include "app_filetransport_api.h"
#include "app_filetransport_api_subsidiary.h"
#include "app_file_event_link.h"
//#include "app_file_packet_api.h"
#include "app_log.h"
#include "device.h"

#define SWITCH_INVALID_NO (0xff)
#define UPDATEME_INVALID_ID (0x00)

static MultiTimer two_way_handle_Timer = {.Handle = 10};
static MultiTimer ota_handle_Timer = {.Handle = 11};
#ifdef HUB_DEVICE
typedef struct{
  char *ptr_count;
  char *ptr_flag;
  unsigned char max;
}bc_producer_timer_t;
static bc_producer_timer_t producer_oneway= {0};
static bc_producer_timer_t producer_twoway = {0};
static bc_producer_timer_t producer_ota = {0};

static unsigned char one_btype_num = 0;   //单向广播btype个数
static unsigned char one_btype[10] = {0};   //单向广播最多存10个

#else
typedef struct{
  char *ptr_flag;
  char ctrl;
}bc_consumer_timer_t;
static bc_consumer_timer_t consumer_twoway = {0};
static bc_consumer_timer_t consumer_ota = {0};
#endif

static unsigned char two_btype_num = 0;   //双向广播btype个数
static unsigned char two_btype[4] = {0};   //双向广播最多存4个 //sounder,keypad,switch,updateme
static unsigned char sounder_bseq = 0x00;
static unsigned char keypad_bseq = 0x00;
static unsigned char switch_bseq = 0x00;
static unsigned char updateme_ctrl = 0x00;
static unsigned char sounder_bitmask[2] = {0x00, 0x00};  //[0]: no.0-no.7 [1]no.8-no.11
static unsigned char keypad_bitmask = 0x00;
static unsigned char switch_no[SWITCH_BC_ID_CN] = {SWITCH_INVALID_NO};
static unsigned char switch_no_num = 0;
static unsigned char updateme_ID[UPDATEME_BC_ID_CN] = {UPDATEME_INVALID_ID};
static unsigned char updateme_ID_num = 0;

static void clean_variable(void)
{
  uint8_t i = 0;
#ifdef HUB_DEVICE
  //ptr_count = NULL;
  //max_retry = 0;
  one_btype_num = 0;
  for(i = 0; i < sizeof(one_btype); i++){
      one_btype[i] = 0x00;
  }
#endif
  //ptr_flag = NULL;
  two_btype_num = 0;
  for(i = 0; i < sizeof(two_btype); i++){
      two_btype[i] = 0;
  }
  sounder_bseq = 0x00;
  keypad_bseq = 0x00;
  switch_bseq = 0x00;
  updateme_ctrl = 0x00;
  for(i = 0; i < sizeof(sounder_bitmask); i++){
      sounder_bitmask[i] = 0;
  }
  keypad_bitmask = 0x00;
  for(i = 0; i < sizeof(switch_no); i++){
      switch_no[i] = SWITCH_INVALID_NO;
  }
  switch_no_num = 0;
  for(i = 0; i < sizeof(updateme_ID); i++){
      updateme_ID[i] = UPDATEME_INVALID_ID;
  }
  updateme_ID_num = 0;
}

static int analysis_twoway_broadcast(char *twoway, int twoway_size)
{
  unsigned char i,j;
  i = j = 0;
  int iret = 0;
  while(i < twoway_size){
      if(twoway[i] == 0x02){
          two_btype[two_btype_num++] = 0x02;
          sounder_bseq = twoway[i+1];
          sounder_bitmask[0] = twoway[i+2];
          sounder_bitmask[1] = twoway[i+3];
          i += 4;
      }else if(twoway[i] == 0x03){
          two_btype[two_btype_num++] = 0x03;
          keypad_bseq = twoway[i+1];
          keypad_bitmask = twoway[i+2];
          i += 3;
      }else if(twoway[i] == 0x04){
          two_btype[two_btype_num++] = 0x04;
          switch_bseq = twoway[i+1];
          switch_no_num = (twoway[i+2] / 2);
          for(j = 0; ((j < switch_no_num) && (j < sizeof(switch_no))); j++){
              switch_no[j] = twoway[i+3+(j*2)];
          }
          i += (3 + (switch_no_num * 2));
      }else if(twoway[i] == 0x08){
          two_btype[two_btype_num++] = 0x08;
          updateme_ID_num = twoway[i+1] - 1;
          updateme_ctrl = twoway[i+2];
          for(j = 0; ((j < updateme_ID_num) && (j < sizeof(updateme_ID))); j++){
              updateme_ID[j] = twoway[i+3+j];
          }
          i += (updateme_ID_num + 3);
      }else{
          iret = 1;
          break;
      }
      if(two_btype_num >= sizeof(two_btype)){
          iret = 2;
          break;
      }
  }
  return iret;
}

#ifdef HUB_DEVICE
static int update_rfm_respons_twoway_broadcast(unsigned char rfmid,
                                               unsigned char btype,
                                               unsigned char bseq)
{
  unsigned char cat = 0xff;
  unsigned char no = 0xff;
  unsigned char i = 0;

  cat = get_cat_from_rfmid(rfmid);
  no = get_no_from_cat_rfmid(cat, rfmid);

  if(no == 0xff){
      return 1;
  }

  if(btype == 0x02){
      if(cat != CAT_SOUNDER){
          return 1;
      }
      if(bseq != sounder_bseq){
          return 2;
      }
      if(no < 8){
          HUB_API_CLEAN_BIT(sounder_bitmask[0], no);
      }else{
          HUB_API_CLEAN_BIT(sounder_bitmask[1], no);
      }
  }else if(btype == 0x03){
      if(cat != CAT_KEYPAD){
          return 1;
      }
      if(bseq != keypad_bseq){
          return 2;
      }
      HUB_API_CLEAN_BIT(keypad_bitmask, no);
  }else if(btype == 0x04){
      if(cat != CAT_IO){
          return 1;
      }
      if(bseq != switch_bseq){
          return 2;
      }
      for(i = 0; i < sizeof(switch_no); i++){
          if(no == switch_no[i]){
              switch_no[i] = SWITCH_INVALID_NO;  //填个无效值
              switch_no_num--;
              break;
          }
      }
  }else if(btype == 0x08){
      if(bseq != updateme_ctrl){
          return 2;
      }
      for(i = 0; i < sizeof(updateme_ID); i++){
          if(rfmid == updateme_ID[i]){
              updateme_ID[i] = UPDATEME_INVALID_ID; //填个无效值
              updateme_ID_num--;
              break;
          }
      }
  }else{
      return 1;
  }
  return 0;
}

static bool check_rfm_all_respons_twoway_broadcast(void)
{
  unsigned char rfmid = 0;
  unsigned char i = 0;

  if(sounder_bitmask[0]){
      for(i = 0; i < 8; i++){
          if(HUB_API_GET_BIT(sounder_bitmask[0], i)){
              rfmid = get_rfmid_from_catno(CAT_SOUNDER, i);
              if(!check_rfm_is_offline(rfmid)){
                  return false;
              }
          }
      }
  }

  if(sounder_bitmask[1]){
      for(i = 0; i < 8; i++){
          if(HUB_API_GET_BIT(sounder_bitmask[1], i)){
              rfmid = get_rfmid_from_catno(CAT_SOUNDER, (i+8));
              if(!check_rfm_is_offline(rfmid)){
                  return false;
              }
          }
      }
  }

  if(keypad_bitmask){
      for(i = 0; i < 8; i++){
          if(HUB_API_GET_BIT(keypad_bitmask, i)){
              rfmid = get_rfmid_from_catno(CAT_KEYPAD, i);
              if(!check_rfm_is_offline(rfmid)){
                  return false;
              }
          }
      }
  }

  if(switch_no_num){
      for(i = 0; i < sizeof(switch_no); i++){
          if(switch_no[i] != SWITCH_INVALID_NO){
              rfmid = get_rfmid_from_catno(CAT_IO, i);
              if(!check_rfm_is_offline(rfmid)){
                  return false;
              }
          }
      }
  }

  if(updateme_ID_num){
      for(i = 0; i < sizeof(updateme_ID); i++){
          if(updateme_ID[i] != UPDATEME_INVALID_ID){
              rfmid = updateme_ID[i];
              if(!check_rfm_is_offline(rfmid)){
                  return false;
              }
          }
      }
  }

  return true;
}

static int get_twoway_broadcast_retry_time(void)
{
  if(!two_btype_num){
      return 0;
  }
#if(0)
  int count = 0;
  int i = 0;
  for(i = 0; i < 8; i++){
      if(HUB_API_GET_BIT(sounder_bitmask[0], i)){
          count++;
      }
      if(HUB_API_GET_BIT(sounder_bitmask[1], i)){
          count++;
      }
      if(HUB_API_GET_BIT(keypad_bitmask, i)){
          count++;
      }
  }
  return (count * HUB_BROADCAST_INTERVAL + HUB_BROADCAST_ALLOWANCE);
#else
  return 49152;
#endif
}

static void hub_to_panel_when_broadcast_finish()
{
  unsigned char msg[255] = {0};
  unsigned char i = 0;
  unsigned char j = 0;
  unsigned char k = 0;
  unsigned char count = 0;
  unsigned char count_idx = 0;
  unsigned char updateme_cat[4][UPDATEME_BC_ID_CN] = {0};
  unsigned char cat_io_idx = 0;
  unsigned char cat_sounder_idx = 0;
  unsigned char cat_keypad_idx = 0;
  unsigned char cat_fob_idx = 0;
  unsigned char cat = 0;
  unsigned char no = 0;

  for(i = 0; i < one_btype_num; i++){
      msg[i] = one_btype[i];
  }
  while(j < two_btype_num){
      msg[i++] = two_btype[j];
      if(two_btype[j] == 0x02){
          msg[i++] = sounder_bseq;
          msg[i++] = CAT_SOUNDER;
          count = 0;
          count_idx = i;
          i++;
          for(k = 0; k < 8; k++){
              if(HUB_API_GET_BIT(sounder_bitmask[0], k)){
                  msg[i++] = k;
                  count++;
              }
          }
          for(k = 0; k < 8; k++){
              if(HUB_API_GET_BIT(sounder_bitmask[1], k)){
                  msg[i++] = (k+8);
                  count++;
              }
          }
          msg[count_idx] = count;
      }else if(two_btype[j] == 0x03){
          msg[i++] = keypad_bseq;
          msg[i++] = CAT_KEYPAD;
          count = 0;
          count_idx = i;
          i++;
          for(k = 0; k < 8; k++){
              if(HUB_API_GET_BIT(keypad_bitmask, k)){
                  msg[i++] = k;
                  count++;
              }
          }
          msg[count_idx] = count;
      }else if(two_btype[j] == 0x04){
          msg[i++] = switch_bseq;
          msg[i++] = CAT_IO;
          msg[i++] = switch_no_num;
          for(k = 0; k < sizeof(switch_no); k++){
              if(switch_no[k] != SWITCH_INVALID_NO){ //非无效No
                  msg[i++] = switch_no[k];
              }
          }
      }else if(two_btype[j] == 0x08){
          msg[i++] = updateme_ctrl;
          for(k = 0; k < sizeof(updateme_ID); k++){
              if(updateme_ID[k] != UPDATEME_INVALID_ID){ //非无效ID
                  cat = get_cat_from_rfmid(updateme_ID[k]);
                  no = get_no_from_cat_rfmid(cat, updateme_ID[k]);
                  if(cat == CAT_IO){
                      updateme_cat[0][cat_io_idx++] = no;
                  }else if(cat == CAT_SOUNDER){
                      updateme_cat[1][cat_sounder_idx++] = no;
                  }else if(cat == CAT_KEYPAD){
                      updateme_cat[2][cat_keypad_idx++] = no;
                  }else if(cat == CAT_FOB){
                      updateme_cat[3][cat_fob_idx++] = no;
                  }else{

                  }
              }
          }
          if(cat_io_idx){
              msg[i++] = CAT_IO;
              msg[i++] = cat_io_idx;
              for(k = 0; k < cat_io_idx; k++){
                  msg[i++] = updateme_cat[0][k];
              }
          }
          if(cat_sounder_idx){
              msg[i++] = CAT_SOUNDER;
              msg[i++] = cat_sounder_idx;
              for(k = 0; k < cat_sounder_idx; k++){
                  msg[i++] = updateme_cat[1][k];
              }
          }
          if(cat_keypad_idx){
              msg[i++] = CAT_KEYPAD;
              msg[i++] = cat_keypad_idx;
              for(k = 0; k < cat_keypad_idx; k++){
                  msg[i++] = updateme_cat[2][k];
              }
          }
          if(cat_fob_idx){
              msg[i++] = CAT_FOB;
              msg[i++] = cat_fob_idx;
              for(k = 0; k < cat_keypad_idx; k++){
                  msg[i++] = updateme_cat[3][k];
              }
          }
      }else{

      }
      j++;
      if(j >= sizeof(two_btype)){
          break;
      }
  }
  if(hub_log_enable){
      DS_app_log_hexdump_error("[BC FINISH]",msg,i);
  }
  if(i){
      DS_hub_api_creat_hub_event(BCAST_FINISH,msg,i);
  }else{
      //如果没有广播信息，不推给panel
  }
  clean_variable();
}

static void timerout_to_broadcast_retry(MultiTimer* timer, void *userData)
{
  (void)timer;
  (void)userData;
  bc_producer_timer_t *ptr_data = (bc_producer_timer_t*)userData;
  FILE_TRANSPORT_E step;
  unsigned char bcast_busy = 0;
  step = get_file_transport_step();
  if(!ptr_data || !ptr_data->ptr_count || !ptr_data->ptr_flag){ //异常结束 参数变了
      if(timer->Handle == two_way_handle_Timer.Handle){
          hub_to_panel_when_broadcast_finish();
      }else if(timer->Handle == ota_handle_Timer.Handle){
          if(step == PRODUCTION_HANDSHAKE){
              setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
          }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
      }else{
          if(step == PRODUCTION_HANDSHAKE){
              setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
          }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
          hub_to_panel_when_broadcast_finish(); //异常结束
      }
      return;
  }

  if((*(ptr_data->ptr_count)) >= ptr_data->max){ //重传次数达到了
      *(ptr_data->ptr_flag) = 0;
      if(timer->Handle == two_way_handle_Timer.Handle){
          hub_to_panel_when_broadcast_finish();
      }else if(timer->Handle == ota_handle_Timer.Handle){
          if(step == PRODUCTION_HANDSHAKE){ //握手时，广播重传次数到了，清除bcast_busy标志
              setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
          }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
      }else{
          if(step == PRODUCTION_HANDSHAKE){
              setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
          }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
          hub_to_panel_when_broadcast_finish(); //异常结束
      }
  }else{
      if(timer->Handle == two_way_handle_Timer.Handle){
          if(check_rfm_all_respons_twoway_broadcast()){
              hub_to_panel_when_broadcast_finish();   //应答超时，但是判断已完成
          }else{
              (*(ptr_data->ptr_count))++;
              *(ptr_data->ptr_flag) = 1;
          }
      }else if(timer->Handle == ota_handle_Timer.Handle){
          (*(ptr_data->ptr_count))++;
          *(ptr_data->ptr_flag) = 1;
      }else{
          if(step == PRODUCTION_HANDSHAKE){
              setThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
          }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
          hub_to_panel_when_broadcast_finish(); //异常结束
      }
  }
}


int start_timer_to_trigger_broadcast_retry(char *oneway, int oneway_size,
                                                 char *twoway, int twoway_size,
                                                 char *count, char max_count,
                                                 char *flag, char ota)
{
  if(!flag || !count){
      return -1;
  }
  unsigned char i = 0;
  int time = 0;
  FILE_TRANSPORT_E step;
  unsigned char updateme_id_num = 0;

  if(ota){
      step = get_file_transport_step();
      if(step == PRODUCTION_NOTIFY || step == PRODUCTION_HANDSHAKE){
          time = OTA_HANDSHAKE_TIMEOUT; //第一次触发时，可能还处于PRODUCTION_NOTIFY状态
      }else if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
          //time = OTA_HANDSHAKE_TIMEOUT; //TODO 这里的时间应该与校验ID个数关联，要改
          getThisParam(ENbyOtaUpdatemeIDNum, &updateme_id_num);
          time = (65536 + updateme_id_num * RFM_LINEUP_INTERVAL);//updateme_id_num * 32768;  //N*2s
      }else{
          time = 0;
      }
      producer_ota.ptr_count = count;
      producer_ota.max = max_count;
      producer_ota.ptr_flag = flag;
      goto finish;
  }

  if(*count == 0){
      clean_variable();
  }

  if(oneway_size){
      if(!oneway){
          return -1;
      }
  }
  if(twoway_size){
      if(!twoway){
          return -1;
      }
  }

  if(oneway_size){
      if(*count == 0){
          one_btype_num = oneway_size;
          for(i = 0; i < one_btype_num; i++){
              one_btype[i] = oneway[i];
          }

          producer_oneway.ptr_count = count;
          producer_oneway.max = max_count;
          producer_oneway.ptr_flag = flag;
      }
      if(!twoway_size){
          if((*count) >= producer_oneway.max){
              hub_to_panel_when_broadcast_finish(); //只有单向广播，且重传次数到了
          }else{
              (*count)++;
              *flag = 1;
          }
          return 0;
      }
  }

  producer_twoway.ptr_count = count;
  producer_twoway.max = max_count;
  producer_twoway.ptr_flag = flag;

  if(twoway_size){
      if(*count == 0){
          analysis_twoway_broadcast(twoway, twoway_size);
          if(switch_no_num){
              if(hub_log_enable){
                  DS_app_log_hexdump_error("[switch_no]",switch_no,switch_no_num);
              }
          }
          if(updateme_ID_num){
              if(hub_log_enable){
                  DS_app_log_hexdump_error("[updateme_ID]",updateme_ID,updateme_ID_num);
              }
          }
      }

      if(check_rfm_all_respons_twoway_broadcast()){
          hub_to_panel_when_broadcast_finish(); //提前结束
          return 0;
      }

      time = get_twoway_broadcast_retry_time();
  }
finish:
  if(time){
      if(ota){
          softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &ota_handle_Timer,0 );
          softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &ota_handle_Timer, time,
                                        timerout_to_broadcast_retry, &producer_ota, 0);
      }else{
          softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &two_way_handle_Timer,0 );
          softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &two_way_handle_Timer, time,
                              timerout_to_broadcast_retry, &producer_twoway, 0);
      }
      return 0;
  }else{
      if(hub_log_enable){
          DS_app_log_error("why 0?");
      }
      if(ota){
          if(step == PRODUCTION_TRANSPORT_FILE || step == PRODUCTION_TRANSPORT_CHECK){
              creat_ota_wait_timeout_event();
          }
      }else{
          hub_to_panel_when_broadcast_finish(); //失败，直接返回结果给panel
      }
      return 1;
  }
}

int maybe_receve_rfm_broadcast_respons(unsigned char rfmid, unsigned char *value_buf, int value_buf_len)
{
  unsigned char btype = 0;
  unsigned char bseq = 0;
  int i = 0;
  unsigned char bcast_busy = 0;
  bool is_my = false;

  getThisParam(ENbyBcastBusy, (unsigned char *)&bcast_busy);
  if(bcast_busy == 0){ //同步广播已完成，不再处理重传的0x2f物模型
      return 1;
  }

  for(i = 0; i < (value_buf_len - 1); i += 2){
      btype = value_buf[i+1];
      bseq = value_buf[i+2];
      if(update_rfm_respons_twoway_broadcast(rfmid, btype, bseq) == 0){
          is_my = true;
      }
  }
  if(is_my == false){ //可能panel紧跟着发下一次广播，但前一次广播的子设备应答重传了，导致不同步
      APP_PRINTF("why not my?\r\n");
      return 2;
  }
  if(check_rfm_all_respons_twoway_broadcast()){
      //广播完成
      hub_to_panel_when_broadcast_finish();
      stop_twoway_broadcast_retry_timer();
  }
  return 0;
}

void stop_ota_broadcast_retry_timer(void)
{
  softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &ota_handle_Timer,0 );
  if(producer_ota.ptr_flag){
      *(producer_ota.ptr_flag) = 0;
  }
}

void stop_twoway_broadcast_retry_timer(void)
{
  softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &two_way_handle_Timer,0 );
  /*强制清除最大上传次数*/
  if(producer_oneway.max){
      producer_oneway.max = 0;
  }
  /*强制清除最大上传次数*/
  if(producer_twoway.max){
      producer_twoway.max = 0;
  }
  if(producer_twoway.ptr_flag){
      *(producer_twoway.ptr_flag) = 0;
  }
}

#else
static int get_twoway_response_time(void)
{
  unsigned char rfmid = 0;
  unsigned char rsps_order = 0;  //第N个顺序 从1开始
  unsigned char no = 0;
  int i = 0;
  int time = 0;

  getThisParam(ENpbyRfmId, &rfmid);
  for(i = 0; i < 8; i++){
      if(HUB_API_GET_BIT(sounder_bitmask[0], i)){
          rsps_order++;
          if(get_rfmid_from_catno(CAT_SOUNDER, i) == rfmid){
              break;
          }
      }
  }
  if(i != 8){
      time = rsps_order * RFM_LINEUP_INTERVAL;
      return time;
  }
  for(i = 0; i < 8; i++){
      if(HUB_API_GET_BIT(sounder_bitmask[1], i)){
          rsps_order++;
          if(get_rfmid_from_catno(CAT_SOUNDER, (i+8)) == rfmid){
              break;
          }
      }
  }
  if(i != 8){
      time = rsps_order * RFM_LINEUP_INTERVAL;
      return time;
  }
  //keypad的应答排第二，
  for(i = 0; i < 8; i++){
      if(HUB_API_GET_BIT(keypad_bitmask, i)){
          rsps_order++;
          if(get_rfmid_from_catno(CAT_KEYPAD, i) == rfmid){
              break;
          }
      }
  }
  if(i != 8){
      time = rsps_order * RFM_LINEUP_INTERVAL;
      return time;
  }
  //普通的（非OTA的）updateme排第三
  if(updateme_ctrl != 0xf0 && updateme_ctrl != 0xf1){
      for(i = 0; i < updateme_ID_num; i++){
          rsps_order++;
          if(rfmid == updateme_ID[i]){
              break;
          }
      }
      if(i != updateme_ID_num){
          time = rsps_order * RFM_LINEUP_INTERVAL;
          return time;
      }
  }

  no = get_no_from_cat_rfmid(CAT_IO, rfmid);
  for(i = 0; i < switch_no_num; i++){
      rsps_order++;
      if(no == switch_no[i]){
          break;
      }
  }
  if(i != switch_no_num){
      time = rsps_order * RFM_LINEUP_INTERVAL;
      return time;
  }
  return time;
}

static void timerout_to_twoway_response(MultiTimer* timer, void *userData)
{
  (void)timer;
  (void)userData;
  unsigned char i = 0;
  keyValue_t keyvalue = {0};

  keyvalue.id = 0x2f;
  keyvalue.valueSize = 0;
  if(two_btype_num == 0){
      return;
  }
  keyvalue.value[keyvalue.valueSize++] = two_btype_num * 2;
  for(i = 0; i < two_btype_num; i++){
      if(two_btype[i] == 0x02){
          keyvalue.value[keyvalue.valueSize++] = 0x02;
          keyvalue.value[keyvalue.valueSize++] = sounder_bseq;
      }else if(two_btype[i] == 0x03){
          keyvalue.value[keyvalue.valueSize++] = 0x03;
          keyvalue.value[keyvalue.valueSize++] = keypad_bseq;
      }else if(two_btype[i] == 0x04){
          keyvalue.value[keyvalue.valueSize++] = 0x04;
          keyvalue.value[keyvalue.valueSize++] = switch_bseq;
      }else if(two_btype[i] == 0x08){
          keyvalue.value[keyvalue.valueSize++] = 0x08;
          keyvalue.value[keyvalue.valueSize++] = updateme_ctrl;
      }else{
          return;
      }
  }
#if (1)
  bc_consumer_timer_t *data = (bc_consumer_timer_t *)userData;
  if(data->ptr_flag){
      *data->ptr_flag = 1;
  }
#endif
  set_BD_key_value(&keyvalue);
}

static bool is_my_twoway_bc(char *twoway, int twoway_size)
{
  int i,j;
  unsigned char switch_len = 0;
  unsigned char updateme_len = 0;
  unsigned char rfmid = 0;
  unsigned char cat = 0;
  unsigned char no = 0;
  i = j = 0;

  getThisParam(ENpbyRfmId, &rfmid);
  cat = get_cat_from_rfmid(rfmid);

  while(i < twoway_size){
      if(twoway[i] == 0x02){
          if(cat == CAT_SOUNDER){
              no = get_no_from_cat_rfmid(CAT_SOUNDER, rfmid);
              if(no < 8){
                  if(HUB_API_GET_BIT(twoway[i+2], no)){
                      return true;
                  }
              }else if(no < 16){
                  if(HUB_API_GET_BIT(twoway[i+3], no)){
                      return true;
                  }
              }
          }
          i += 4;
      }else if(twoway[i] == 0x03){
          if(cat == CAT_KEYPAD){
              no = get_no_from_cat_rfmid(CAT_KEYPAD, rfmid);
              if(no < 8){
                  if(HUB_API_GET_BIT(twoway[i+2], no)){
                      return true;
                  }
              }
          }
          i += 3;
      }else if(twoway[i] == 0x04){
          no = get_no_from_cat_rfmid(CAT_IO, rfmid);
          if(no != 0xff){
              switch_len = (twoway[i+2] / 2);
              for(j = 0; ((j < switch_len)); j++){
                  if(no == twoway[i+3+(j*2)]){
                      return true;
                  }
              }
          }
          i += (3 + (switch_len * 2));
      }else if(twoway[i] == 0x08){
          updateme_len = twoway[i+1] - 1;
          for(j = 0; ((j < updateme_len)); j++){
              if(rfmid == twoway[i+3+j]){
                  return true;
              }
          }
          i += (updateme_len + 3);
      }else{
          return false;
      }
  }
  return false;
}

int start_timer_to_trigger_twoway_response(char *twoway, int twoway_size, char *flag)
{
  if(!flag){
      return -1;
  }

  if(twoway_size){
      if(!twoway){
          return -1;
      }
  }

  int time = 0;

  if(!is_my_twoway_bc(twoway , twoway_size)){
      return 1;
  }

  consumer_twoway.ptr_flag = flag;
  clean_variable();

  analysis_twoway_broadcast(twoway, twoway_size);

  time = get_twoway_response_time();
  if(time){
      softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &two_way_handle_Timer,0 );
      softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &two_way_handle_Timer, time,
                              timerout_to_twoway_response, &consumer_twoway, 0);
  }else{
      //updateme_ctrl 0xf0 0xf1，延续原逻辑
  }
  return 0;
}

static int get_updateme_response_time(void)
{
  unsigned char rfmid = 0;
  unsigned char rsps_order = 0;  //第N个顺序 从1开始
  int i = 0;
  int time = 0;

  unsigned char updateme_id_num = 0;
  unsigned char updateme_id[OTA_ID_BUF_MAX] = {0};

  getThisParam(ENpbyRfmId, &rfmid);
  getThisParam(ENbyOtaUpdatemeID, updateme_id);      //ota ID[]
  getThisParam(ENbyOtaUpdatemeIDNum, &updateme_id_num);     //ota ID长度
  for(i = 0; i < updateme_id_num; i++){
      rsps_order++;
      if(updateme_id[i] == rfmid){
          break;
      }
  }
  if(i != updateme_id_num){
      time = rsps_order * RFM_LINEUP_INTERVAL;
      return time;
  }
  return time;
}

static void timerout_to_updateme_response(MultiTimer* timer, void *userData)
{
  (void)timer;
  (void)userData;
  keyValue_t keyvalue = {0};

  bc_consumer_timer_t *data = (bc_consumer_timer_t *)userData;
  if(data->ctrl == 0xf0){
      //推送物模型
      keyvalue.id = 0xff;
      keyvalue.valueSize = OTA_REQUEST_VALUE_LENGTH;
      getThisParam(ENbyOtaRequestKeyValue, &keyvalue.value);
      if(keyvalue.valueSize){
          set_key_value(&keyvalue);
          if(data->ptr_flag){
              *data->ptr_flag = 1;
          }
      }
  }else if(data->ctrl == 0xf1){
      //推送物模型
      keyvalue.id = 0xfb;
      packet_check_response(keyvalue.value, &keyvalue.valueSize);
      if(keyvalue.valueSize){
          set_key_value(&keyvalue);
          if(data->ptr_flag){
              *data->ptr_flag = 1;
          }
      }
  }
}

int start_timer_to_trigger_updateme_response(char *msg, int msg_size, char *flag)
{
  /*if(!flag){
      return -1;
  }*/

  if(msg_size){
      if(!msg){
          return -1;
      }
  }
  int time = 0;
  if(msg[0] == 1){ //OTA的updateme //ctrl 0xf0 0xf1
      consumer_ota.ctrl = msg[1];
      consumer_ota.ptr_flag = flag;
      time = get_updateme_response_time();
      if(time){
          softwareMultiTimerStop(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &ota_handle_Timer,0 );
          softwareMultiTimerStart(EN_LP_HARD_TIMER_EM3_SYS_RTC_1, &ota_handle_Timer, time,
                                  timerout_to_updateme_response, &consumer_ota, 0);
      }else{
      }
  }else{
  }
  return 0;
}
#endif
